package com.monitor.rest;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;

import com.ms.MsConfig;
import com.ms.msclient.MsClientResponse;
import com.system.auth.AuthUtil;
import com.system.comm.utils.FrameFileUtil;
import com.system.comm.utils.FrameJsonUtil;
import com.system.comm.utils.FrameSpringBeanUtil;
import com.system.handle.model.ResponseCode;
import com.system.handle.model.ResponseFrame;

/**
 * 微服务请求
 * @author yuejing
 * @date 2019年7月25日 下午3:53:36
 */
public class MsRequestUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(MsRequestUtil.class);

	/**
	 * 请求微服务
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static ResponseFrame post(String serviceId, String url, Map<String, Object> params) {
		return post(MsConfig.getClientId(), MsConfig.getSercret(), serviceId, url, params);
	}
	/**
	 * 请求微服务
	 * @param clientId
	 * @param sercret
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static ResponseFrame post(String clientId, String sercret, String serviceId, String url, Map<String, Object> params) {
		String time = String.valueOf(System.currentTimeMillis());
		params.put("clientId", clientId);
		params.put("time", time);
		params.put("sign", AuthUtil.auth(clientId, time, sercret));
		RestUtil restUtil = FrameSpringBeanUtil.getBean(RestUtil.class);
		ResponseFrame frame = restUtil.request(serviceId, url, params);
		if(ResponseCode.SUCC.getCode() != frame.getCode().intValue()) {
			LOGGER.error("{} - {}: {}", serviceId, url, FrameJsonUtil.toString(frame));
			frame.setBody(null);
		}
		return frame;
	}

	/**
	 * 请求微服务
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static ResponseFrame postJsonBody(String serviceId, String url, Map<String, Object> params) {
		return postJsonBody(MsConfig.getClientId(), MsConfig.getSercret(), serviceId, url, params);
	}
	/**
	 * 请求微服务
	 * @param clientId
	 * @param sercret
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static ResponseFrame postJsonBody(String clientId, String sercret, String serviceId, String url, Map<String, Object> params) {
		String time = String.valueOf(System.currentTimeMillis());
		params.put("clientId", clientId);
		params.put("time", time);
		params.put("sign", AuthUtil.auth(clientId, time, sercret));
		RestUtil restUtil = FrameSpringBeanUtil.getBean(RestUtil.class);
		ResponseFrame frame = restUtil.requestJsonBody(serviceId, url, params);
		if(ResponseCode.SUCC.getCode() != frame.getCode().intValue()) {
			LOGGER.error("{} - {}: {}", serviceId, url, FrameJsonUtil.toString(frame));
			frame.setBody(null);
		}
		return frame;
	}


	/**
	 * 请求微服务
	 * @param <T>
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static <T> MsClientResponse<T> postMsClient(String serviceId, String url, Map<String, Object> params, Class<?> responseClazz, Class<?> responsePageClazz) {
		return postMsClient(MsConfig.getClientId(), MsConfig.getSercret(), serviceId, url, params, responseClazz, responsePageClazz);
	}
	/**
	 * 请求微服务
	 * @param clientId
	 * @param sercret
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static <T> MsClientResponse<T> postMsClient(String clientId, String sercret, String serviceId, String url, Map<String, Object> params, Class<?> responseClazz, Class<?> responsePageClazz) {
		String time = String.valueOf(System.currentTimeMillis());
		params.put("clientId", clientId);
		params.put("time", time);
		params.put("sign", AuthUtil.auth(clientId, time, sercret));
		RestUtil restUtil = FrameSpringBeanUtil.getBean(RestUtil.class);
		MsClientResponse<T> frame = restUtil.requestMsClient(serviceId, url, params, responseClazz, responsePageClazz);
		if(ResponseCode.SUCC.getCode() != frame.getCode().intValue()) {
			LOGGER.error("{} - {}: {}", serviceId, url, FrameJsonUtil.toString(frame));
			frame.setBody(null);
		}
		return frame;
	}

	/**
	 * 请求微服务
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static <T> MsClientResponse<T> postMsClientJsonBody(String serviceId, String url, Map<String, Object> params, Class<?> responseClazz, Class<?> responsePageClazz) {
		return postMsClientJsonBody(MsConfig.getClientId(), MsConfig.getSercret(), serviceId, url, params, responseClazz, responsePageClazz);
	}
	/**
	 * 请求微服务
	 * @param clientId
	 * @param sercret
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static <T> MsClientResponse<T> postMsClientJsonBody(String clientId, String sercret, String serviceId, String url, Map<String, Object> params, Class<?> responseClazz, Class<?> responsePageClazz) {
		String time = String.valueOf(System.currentTimeMillis());
		params.put("clientId", clientId);
		params.put("time", time);
		params.put("sign", AuthUtil.auth(clientId, time, sercret));
		RestUtil restUtil = FrameSpringBeanUtil.getBean(RestUtil.class);
		MsClientResponse<T> frame = restUtil.requestMsClientJsonBody(serviceId, url, params, responseClazz, responsePageClazz);
		if(ResponseCode.SUCC.getCode() != frame.getCode().intValue()) {
			LOGGER.error("{} - {}: {}", serviceId, url, FrameJsonUtil.toString(frame));
			frame.setBody(null);
		}
		return frame;
	}

	/**
	 * 上传文件
	 * @param serviceId
	 * @param url
	 * @param file
	 * @param params
	 * @param responseClazz
	 * @return
	 */
	public static <T> MsClientResponse<T> uploadMsClient(String serviceId, String url, File file, Map<String, Object> params, Class<?> responseClazz) {
		return uploadMsClient(MsConfig.getClientId(), MsConfig.getSercret(), serviceId, url, file, params, responseClazz);
	}
	public static <T> MsClientResponse<T> uploadMsClient(String clientId, String sercret, String serviceId, String url, File file, Map<String, Object> params, Class<?> responseClazz) {
		String time = String.valueOf(System.currentTimeMillis());
		params.put("clientId", clientId);
		params.put("time", time);
		params.put("sign", AuthUtil.auth(clientId, time, sercret));
		RestUtil restUtil = FrameSpringBeanUtil.getBean(RestUtil.class);
		MsClientResponse<T> frame = restUtil.uploadMsClient(serviceId, url, file, params, responseClazz);
		if(ResponseCode.SUCC.getCode() != frame.getCode().intValue()) {
			LOGGER.error("{} - {}: {}", serviceId, url, FrameJsonUtil.toString(frame));
			frame.setBody(null);
		}
		return frame;
	}

	/**
	 * 下载文件
	 * @param clientId
	 * @param sercret
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static ResponseEntity<byte[]> downloadMsClient(String serviceId, String url, Map<String, Object> params) {
		return downloadMsClient(MsConfig.getClientId(), MsConfig.getSercret(), serviceId, url, params);
	}
	/**
	 * 下载文件
	 * @param clientId
	 * @param sercret
	 * @param serviceId
	 * @param url
	 * @param params
	 * @return
	 */
	public static ResponseEntity<byte[]> downloadMsClient(String clientId, String sercret, String serviceId, String url, Map<String, Object> params) {
		String time = String.valueOf(System.currentTimeMillis());
		params.put("clientId", clientId);
		params.put("time", time);
		params.put("sign", AuthUtil.auth(clientId, time, sercret));
		RestUtil restUtil = FrameSpringBeanUtil.getBean(RestUtil.class);
		return restUtil.downloadMsClient(serviceId, url, params);
	}
	/**
	 * 将流保存为文件
	 * @param response
	 * @param savePath
	 */
	public static void downloadSaveFile(ResponseEntity<byte[]> response, String savePath) {
		InputStream inputStream = null;
		OutputStream outputStream = null;
		try {
			File file = new File(savePath);
			FrameFileUtil.createDir(file);
			// 取得文件字节
			byte[] result = response.getBody();
			if (result == null) {
				result = new byte[0];
			}
			inputStream = new ByteArrayInputStream(result);
			outputStream = new FileOutputStream(file);
			int len = 0;
			byte[] buf = new byte[1024];
			while ((len = inputStream.read(buf, 0, 1024)) != -1) {
				outputStream.write(buf, 0, len);
			}
			outputStream.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(inputStream != null) {
					inputStream.close();
				}
				if(outputStream != null) {
					outputStream.close();
				}
			} catch (IOException e) {
			}
		}
	}
}
